package com.microsec.iot.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.node.ObjectNode;

import java.io.IOException;

public class JsonUtil {

    private static ObjectMapper objectMapper;

    static {
        objectMapper = new ObjectMapper();

        // 设置FAIL_ON_EMPTY_BEANS属性，当序列化空对象不要抛异常
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);

        // 设置FAIL_ON_UNKNOWN_PROPERTIES属性，当JSON字符串中存在Java对象没有的属性，忽略
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    public static JsonNode stringToObject(String jsonString) {
    	ObjectMapper mapper = new ObjectMapper();
        // Jackson提供一个树节点被称为"JsonNode",ObjectMapper提供方法来读json作为树的JsonNode根节点
    	JsonNode node = null;
        try {
        	node = mapper.readTree(jsonString);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
        return node;
    }
    /**
     * Convert Object to JsonString
     * 
     * @param jsonObj
     * @return
     */
    public static String jsonObj2Sting(Object jsonObj) {
        String jsonString = null;

        try {
            jsonString = objectMapper.writeValueAsString(jsonObj);
        } catch (IOException e) {
            System.out.printf("pasre json Object[{}] to string failed.",jsonString);
        }

        return jsonString;
    }

    /**
     * Convert JsonString to Simple Object
     * 
     * @param jsonString
     * @param cls
     * @return
     */
    public static <T> T jsonString2SimpleObj(String jsonString, Class<T> cls) {
        T jsonObj = null;

        try {
            jsonObj = objectMapper.readValue(jsonString, cls);
        } catch (IOException e) {
        	System.out.printf("pasre json Object[{}] to string failed.",jsonString);
        }

        return jsonObj;
    }
   
    /**
     * Method that will convert object to the ObjectNode.
     *
     * @param value
     *            the source data; if null, will return null.
     * @return the ObjectNode data after converted.
     * @throws JsonException
     */
    public static <T> ObjectNode convertObject2ObjectNode(T object)
            throws Exception {
        if (null == object) {
            return null;
        }

        ObjectNode objectNode = null;

        if (object instanceof String) {
            objectNode = convertJsonStringToObject((String) object,
                    ObjectNode.class);
        } else {
            objectNode = convertValue(object, ObjectNode.class);
        }

        return objectNode;
    }
    
    /**
     * Method that will convert the json string to destination by the type(cls).
     * 
     * @param jsonString
     *            the source json string; if null, will return null.
     * @param cls
     *            the destination data type.
     * @return
     * @throws JsonException
     */
    public static <T> T convertJsonStringToObject(String jsonString,
            Class<T> cls) throws Exception {
        if (StringUtil.strIsNullOrEmpty(jsonString)) {
            return null;
        }

        try {
            T object = objectMapper.readValue(jsonString, cls);
            return object;
        } catch (Exception e) {
            throw new Exception(e);
        }
    }
    
    /**
     * Method that will convert from given value into instance of given value
     * type.
     * 
     * @param fromValue
     * @param toValueType
     * @return
     * @throws JsonException
     */
    private static <T> T convertValue(Object fromValue, Class<T> toValueType)
            throws Exception {
        try {
            return objectMapper.convertValue(fromValue, toValueType);
        } catch (IllegalArgumentException e) {
            throw new Exception(e);
        }
    }
    
    public static void main(String args[]) {
    	String jsonString = "{\"notifyType\":\"deviceDataChanged\",\"deviceId\":\"c5aa309c-b168-4ac2-ae5c-a818eb16ea46\",\"gatewayId\":\"c5aa309c-b168-4ac2-ae5c-a818eb16ea46\",\"requestId\":null,\"service\":{\"serviceId\":\"Temp\",\"serviceType\":\"Temp\",\"data\":{\"data\":null},\"eventTime\":\"20180706T095008Z\"}}";
    	JsonNode node = stringToObject(jsonString);
    	String type = "\"deviceDataChanged\"";
    	// .equals("\"deviceDataChanged\"")
    	System.out.println(node.get("notifyType").toString());
    	System.out.println(type);
    	System.out.println(type.equals(node.get("notifyType").toString()));
    }
}
